<template>
  <div ref="canvas"></div>
</template>

<script lang="ts" setup>
import * as THREE from "three";
import Stats from "three/examples/jsm/libs/stats.module";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js";
import {ref, onMounted, render} from "vue";
import {addLargeGroundPlane, initDefaultLighting} from "@/book/ThreeUtils";

const canvas = ref();

let scene = new THREE.Scene();
// 渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x000000);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
// 相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight);
camera.position.set(-10, 20, 20);
camera.lookAt(scene.position);
// 相机控件
const orbitControl = new OrbitControls(camera, renderer.domElement);
orbitControl.update();
// 性能统计
const stat = Stats();
// light
initDefaultLighting(scene, undefined);
// plane
const planeGeometry = new THREE.PlaneGeometry(60, 20, 1, 1);
const planeMaterial = new THREE.MeshLambertMaterial({
  color: 0xffffff
});
const plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -0.5 * Math.PI;
plane.position.set(15, 0, 0);
scene.add(plane);
// cube
const cubeGeom = new THREE.BoxGeometry(4, 4, 4);
const cubeMaterial = new THREE.MeshLambertMaterial({
  color: 0xff0000
});
const cube = new THREE.Mesh(cubeGeom, cubeMaterial);
cube.position.set(-4, 3, 0);
scene.add(cube);
// sphere
const sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
const sphereMaterial = new THREE.MeshLambertMaterial({
  color: 0x7777ff
});
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(20, 0, 2);
scene.add(sphere);
// gui
const controls = {
  exportScene: () => {
    localStorage.setItem('scene', JSON.stringify(scene.toJSON()));
    console.log("场景导出为JSON并存储到localStorage: ", localStorage.getItem("scene"));
  },
  clearScene: () => {
    scene = new THREE.Scene();
  },
  importScene: () => {
    const json = (localStorage.getItem('scene'));

    if (json) {
      const loadedSceneAsJson = JSON.parse(json);
      const loader = new THREE.ObjectLoader();
      scene = loader.parse(loadedSceneAsJson);
    }
  },
};

const gui = new GUI();
// @ts-ignore
gui.add(controls, "exportScene").name("导出场景为JSON");
// @ts-ignore
gui.add(controls, "clearScene").name("清除场景");
// @ts-ignore
gui.add(controls, "importScene").name("从JSON导入场景");

const render = () => {
  stat.update();

  requestAnimationFrame(render);
  renderer.render(scene, camera);
};

onMounted(() => {
  canvas.value.appendChild(stat.domElement);
  canvas.value.appendChild(renderer.domElement);
  render();
});

</script>
